﻿#ifndef FORMATCONVERT_H
#define FORMATCONVERT_H

#include <QObject>
#include <QVideoFrame>

extern "C"
{
#include "libavformat/avformat.h"
};

class FormatConvert : public QObject
{
    Q_OBJECT
public:
    /* 转同宽高 */
    static AVFrame *convertToFrame(const QVideoFrame &frame, QVideoFrame::PixelFormat _dstFormat);

    /**
     * @brief convertToFrame 将Qt图像帧，转为FFmpeg帧
     * @param frame 视频源
     * @param dstW  目标宽度
     * @param dstH  目标高度
     * @param _dstFormat    目标格式
     * @return FFmpeg帧
     */
    static AVFrame * convertToFrame(const QVideoFrame &frame,int dstW,int dstH,QVideoFrame::PixelFormat _dstFormat);


    /**
     * @brief audio_rescale 重采样是将源（采样率、声道数、采样精度）转换为目标（采样率、声道数、采样精度），由于值可能发生变化，故采样点数可能发生变化。
     * @param srcFrame      源数据（包括可用得采样率、声道、格式、采样点个数）
     * @param dstSampleRate 目标采样率
     * @param dstChannels   目标声道,warning!只支持单>单,双>双
     * @param dstSampleFormat   目标格式
     * @param outBuf        返回数据，注：传入时需要空间有效
     * @param outBufSize    返回数据字节数
     * @param outNbSamples  返回样本点
     * @return  0 成功，其他值失败
     */
    static int audio_rescale(AVFrame *srcFrame,int dstSampleRate, int dstChannels, enum AVSampleFormat dstSampleFormat,
                             uint8_t *outBuf, int *outBufSize, int *outNbSamples);


    /**
     * @brief audio_rescale
     * @param srcFrame 源AVFrame
     * @param dstFrame 目标帧，需已初始化，并设置必要参数（目的采样率、目标声道、目标样本数、目标格式）,warning!只支持单>单,双>双
     * @return 0成功，其他失败
     * @example:
     * AVFrame *audioFrame = av_frame_alloc();
     * audioFrame->sample_rate = SAMPLE_RATE;
     * audioFrame->channels = 2;
     * audioFrame->format = AV_SAMPLE_FMT_S16;
     * audioFrame->channel_layout = av_get_default_channel_layout(audioFrame->channels);
     * audioFrame->nb_samples = av_rescale_rnd(frame->nb_samples, audioFrame->sample_rate, frame->sample_rate, AV_ROUND_UP);
     * if (av_frame_get_buffer(audioFrame,0) < 0) {
     *   Q_ASSERT(false);
     * }
     *
     * // do other...
     *
     * av_frame_free(&audioFrame);
     */
    static int audio_rescale(AVFrame *srcFrame,AVFrame *dstFrame);

private:
    explicit FormatConvert();

};

#endif // FORMATCONVERT_H
